#include "Scene.h"

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <iostream>

using namespace std;

static void
initGL
(int w, int h)
{
  glViewport(0, 0, w, h);
  glClearColor(0.2, 0.2, 0.2, 0.0);
  glColor3f(1.0, 1.0, 1.0);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);

  // Enable basic lighting.
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);

  gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 1.0, 10.0);
  glMatrixMode(GL_MODELVIEW);
  
  glEnable(GL_DEPTH_TEST);
}

static SDL_Surface*
initSDL
(int w, int h, const char *caption)
{
  SDL_Surface* sf = 0;

  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    cerr << "SDL_Init: " << SDL_GetError() << endl;
    return 0;
  }

  // Activate double buffering.
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

  sf = SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_DOUBLEBUF);
  if (sf == 0) {
    cerr << "SDL_SetVideoMode: " << SDL_GetError() << endl;
    SDL_Quit();
    return 0;
  }

  SDL_WM_SetCaption(caption, 0);

  // Initialize OpenGL.
  initGL(w, h);

  return sf;
}

static uint32_t
frame_update
(uint32_t interval, void *param)
{
  SDL_Event ev;
  ev.type = SDL_USEREVENT;
  ev.user.code = 0;
  
  SDL_PushEvent(&ev);
  return interval;
}

int
main
(int argc, char ** argv)
{
  bool done;
  bool fs(false);

  // Initiliaze SDL.
  SDL_Surface *sf = initSDL(640, 480, "OpenGL / Optimizations");
  // Full screen?
  if (fs) SDL_WM_ToggleFullScreen(sf);

  // Adds a timer which will call a callback after 
  // the specified number of milliseconds has elapsed.
  SDL_AddTimer(100, frame_update, 0);
  
  SDL_Event event;

  done = false;

  // Create the scene.
  Scene sc(sf);
  
  int fps = 0, frames = 0;
  int current_time = SDL_GetTicks();

  while (!done) {

    if (SDL_PollEvent(&event)) {

      if (event.type == SDL_QUIT) done = true;

      else if (event.type == SDL_KEYDOWN) {

    	uint32_t sym = event.key.keysym.sym;

    	switch (sym) {
    	  // Exit when typing 'q' or ESC.
    	case SDLK_q:
    	case SDLK_ESCAPE:
    	  done = true;
    	  break;
	
    	  // Full Screen when typing 'f'.
    	case SDLK_f:
    	  SDL_WM_ToggleFullScreen(sf);
    	  break;

    	  // Display List.
    	case SDLK_d:	  
    	  break;
	
    	  // Default event other than 'f', 'd', 'q' or ESC.
    	default:
	  sc.draw();
    	}// End switch.
	
      }

    }
    else {
      sc.draw();
    }

  }// End while

  SDL_Quit();
  return 0;
}
